package com.cumulus.acceleration;

import java.util.ArrayList;

import android.util.Log;

import com.cumulus.acceleration.AccAng;
import java.lang.Math;
import android.util.Log; 
import android.util.FloatMath;

public class Compare {
	float mean = 0;
	private static final float C = (float) 0.3;
	private static final float mulC = (float) 0;
	private static final float mulD = (float) 0.5;
	private static final int nSaved = 10;
	private static final String TAG = "App";
	
	private float distance(float xC, float yC, float zC, float xA, float yA, float zA) {
		return FloatMath.sqrt(((xA * xA) + (yA * yA) + (zA * zA)) + ((xC * xC) + (yC * yC) + (zC * zC)));
	}
	
	private float distance(AccAng a) {
		float xA = a.xA, yA = a.yA, zA = a.zA, xC = a.xC, yC = a.yC, zC = a.zC;
		return FloatMath.sqrt((C * C * (xA * xA + yA * yA + zA * zA) + (xC * xC + yC * yC + zC * zC)));
	}
	
	public float compare(ArrayList<AccAng> a, ArrayList<AccAng> b) {
		float rxC, ryC, rzC, rxA, ryA, rzA;
		int N = 0; // Minimum size between a and b. To be sure not to get
					// IndexOutOfBounds
		if (a.size() < b.size())
			N = a.size();
		else
			N = b.size();
		mean = 0;
		for(int i = 0; i < N; i++) {
			Log.d(TAG, a.get(i).xA + " " + b.get(i).xA);
			Log.d(TAG, a.get(i).xC + " " + b.get(i).xC);
		}
		for (int i = 0; i < N; i++) {
			if (a.get(i).xC > 1.0)
				rxC = (a.get(i).xC - b.get(i).xC) / a.get(i).xC;
			else if (b.get(i).xC < 1.0)
				rxC = 0;
			else
			
				rxC = (a.get(i).xC - b.get(i).xC) / b.get(i).xC;
			
			if (a.get(i).yC > 1.0)
				ryC = (a.get(i).yC - b.get(i).yC) / a.get(i).yC;
			else if (b.get(i).yC < 1.0)
				ryC = 0;
			else
				ryC = (a.get(i).yC - b.get(i).yC) / b.get(i).yC;
			if (a.get(i).zC > 1.0)
				rzC = (a.get(i).zC - b.get(i).zC) / a.get(i).zC;
			else if (b.get(i).zC < 1.0)
				rzC = 0;
			else
				rzC = (a.get(i).zC - b.get(i).zC) / b.get(i).zC;

			if (a.get(i).xA > 1.0)
				rxA = (a.get(i).xA - b.get(i).xA) / a.get(i).xA;
			else if (b.get(i).xA < 1.0)
				rxA = 0;
			else
				rxA = (a.get(i).xA - b.get(i).xA) / b.get(i).xA;
			if (a.get(i).yA > 1.0)
				ryA = (a.get(i).yA - b.get(i).yA) / a.get(i).yA;
			else if (b.get(i).yA < 1.0)
				ryA = 0;
			else
				ryA = (a.get(i).yA - b.get(i).yA) / b.get(i).yA;
			if (a.get(i).zA > 1.0)
				rzA = (a.get(i).zA - b.get(i).zA) / a.get(i).zA;
			else if (b.get(i).yA < 1.0)
				rzA = 0;
			else
				rzA = (a.get(i).zA - b.get(i).zA) / b.get(i).zA;
			Log.d(TAG, "Added distance is: "+ distance(rxC, ryC, rzC, rxA, ryA, rzA));
			mean = mean + distance(rxC, ryC, rzC, rxA, ryA, rzA);
		}
		mean = mean / N;
		return mean;
	}
	
	public float meanDist(ArrayList<AccAng> a) {
		float mean_a = (float) 0.0;
		for(AccAng el : a){
			mean_a += distance(el);
		}
		mean_a = mean_a / a.size();
		return mean_a;
	}
	
	public float meanDev(ArrayList<AccAng> a, float meanA) {
		float devA = (float) 0.0;
		for(AccAng el : a){
			devA += Math.abs(distance(el) - meanA);
		}
		return devA / a.size();
	}
	
	public float adaptiveCompare(ArrayList<AccAng> a, ArrayList<AccAng> b) {
		Log.d(TAG, a.size() + " " + b.size());
		ArrayList<AccAng> aParsed = new ArrayList<AccAng>();
		ArrayList<AccAng> bParsed = new ArrayList<AccAng>();
		float mean_a = meanDist(a), mean_b = meanDist(b);
		float dev_a = meanDev(a, mean_a), dev_b = meanDev(b, mean_b);
		Log.d(TAG, mean_a + " " + dev_a + " " + mean_b + " " + dev_b);
		for(AccAng elA : a) 
			if(distance(elA.xC, elA.yC, elA.zC, elA.xA, elA.yA, elA.zA) > mean_a + mulC * dev_a)
				aParsed.add(elA);
		for(AccAng elB :b) 
			if(distance(elB.xC, elB.yC, elB.zC, elB.xA, elB.yA, elB.zA) > mean_b + mulC * dev_a)
				bParsed.add(elB);
		Log.d(TAG, aParsed.size() + " " + bParsed.size());
		return compare(aParsed, bParsed) * (((mean_a / mean_b) + (mean_b / mean_a) - (float) 1.95));
	}
	
	
	public float compareRT(ArrayList<AccAng> a, ArrayList<AccAng> b, AccAng addA, AccAng addB, int i)
	{
		mean = mean * nSaved;
		if(i > nSaved) {
			mean -= distance(a.get(i - nSaved).xC - b.get(i - nSaved).xC, a.get(i - nSaved).yC - b.get(i - nSaved).yC, a.get(i - nSaved).zC - b.get(i - nSaved).zC, 
					 a.get(i - nSaved).xA - b.get(i - nSaved).xA, a.get(i - nSaved).yA - b.get(i - nSaved).yA, a.get(i - nSaved).zA - b.get(i - nSaved).zA);
			mean += distance(addA.xC - addB.xC, addA.yC - addB.yC, addA.zC - addB.zC,
					addA.xA - addB.xA, addA.yA - addB.yA, addA.zA - addB.zA);
			return mean / nSaved;
		}
		return 0;
	}
}
